/**
 * Copyright 2012 Viettel Telecom. All rights reserved.
 * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package webdev.utils;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.util.FloatMath;
import android.util.Log;
import android.widget.ImageView;

/**
 *  Cac ham util ve xu ly hinh anh
 *  @author: TruongLT
 *  @version: 1.0
 *  @since: 1.0
 */
public class ImageUtil {

	/**
	*  get bitmap khi thuc hien chon anh tu thu muc picasa cua gallery
	*  @author: BangHN
	*  @param image
	*  @throws IOException
	*  @return: Bitmap
	*  @throws:
	*/
	public static Bitmap getBitmapFromPicasaUri(Uri image, Context mContext) throws IOException{
		Bitmap bitmap = null;
		InputStream is = null;
		try {
			//is = GlobalInfo.getInstance().getAppContext().getContentResolver().openInputStream(image);
			is = mContext.getContentResolver().openInputStream(image);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			int read;
			byte[] b = new byte[4096];
			while ((read = is.read(b)) != -1) {
				out.write(b, 0, read);
			}
			byte[] raw = out.toByteArray();
			bitmap =  BitmapFactory.decodeByteArray(raw, 0, raw.length);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally{
			if(is != null){
				is.close();
			}
		}
		return bitmap;
	}

	public static Bitmap readImageFromSDCard(String path) {
		Bitmap image = null;
		FileInputStream iStream = null;
		try {
			System.gc();
			iStream = new FileInputStream(path);
			BufferedInputStream bis = null;
			bis = new BufferedInputStream(iStream);
			image = BitmapFactory.decodeStream(bis);
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (iStream != null) {
				try {
					iStream.close();
				} catch (IOException ex) {
					// TODO: handle exception
				}
			}
		}
		return image;
	}

	public static Bitmap readImageFromRes(Resources rs, int FileID) {
		Bitmap mBitmap = BitmapFactory.decodeResource(rs, FileID);
		return mBitmap;
	}


	/**
	 * 
	 * load image from url, not cache
	 * 
	 * @author: DoanDM
	 * @param url
	 * @return
	 * @return: Drawable
	 * @throws:
	 */
	public static void LoadImageFromWebOperations(Activity act,
			final String url, final ImageView iv) {
		act.runOnUiThread(new Runnable() {
			public void run() {
				try {
					InputStream is = (InputStream) new URL(url).getContent();
					Drawable d = Drawable.createFromStream(is, "src name");
					iv.setImageDrawable(d);
				} catch (Exception e) {
					System.out.println("Exc=" + e);
				}
			}
		});

	}


	public static boolean writeFileImageToPhone(Bitmap bm, String filename,
			String fileType) {
		boolean isWrite = false;
		String extStorageDirectory = Environment.getExternalStorageDirectory()
				.toString();

		Log.i("ImageUtil", "extStorageDirectory: " + extStorageDirectory);
		OutputStream outStream = null;
		File file = new File(extStorageDirectory, filename + "." + fileType);
		try {
			outStream = new FileOutputStream(file);
			if (fileType.endsWith("PNG")) {
				bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
			} else if (fileType.endsWith("JPEG")) {
				bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
			}

			try {
				outStream.flush();
				outStream.close();
				isWrite = true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return isWrite;
	}

	/*
	 * method convert bitmap to byte[]
	 */
	public static byte[] convertBitmapToByteArray(Bitmap bm) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
		byte[] data = baos.toByteArray();
		return data;
	}

	public static Bitmap resizeImage(Bitmap orignal, int new_width,
			int new_height) {
		// load the origial BitMap
		int width = orignal.getWidth();
		int height = orignal.getHeight();

		float scaleWidth = ((float) new_width) / width;
		float scaleHeight = ((float) new_height) / height;
		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);
		Bitmap resizedBitmap = Bitmap.createBitmap(orignal, 0, 0, width,
				height, matrix, true);
		return resizedBitmap;
	}

	public static Bitmap rotateBitmap(Bitmap orignal, int degrees) {
		int width = orignal.getWidth();
		int height = orignal.getHeight();
		Matrix matrix = new Matrix();
		// matrix.postScale(width, height);
		if (degrees != 0) {
			matrix.postRotate(degrees);
		}
		Bitmap rotateBitmap = Bitmap.createBitmap(orignal, 0, 0, width, height,
				matrix, true);
		orignal.recycle();
		orignal = null;
		return rotateBitmap;
	}

	public static Bitmap resizeImageWithOrignal(Bitmap orignal,
			int maxDimension, int degrees) {
		System.gc();
		int width = orignal.getWidth();
		int height = orignal.getHeight();

		if (width > maxDimension || height > maxDimension) {
			int new_width;
			int new_height;
			float ratio = (float) width / height;
			if (ratio > 1.0f) {
				new_width = maxDimension;
				new_height = (int) ((float) new_width / ratio);
			} else {
				new_height = maxDimension;
				new_width = (int) ((float) new_height * ratio);
			}
			float scaleWidth = ((float) new_width) / width;
			float scaleHeight = ((float) new_height) / height;
			Matrix matrix = new Matrix();
			matrix.postScale(scaleWidth, scaleHeight);
			if (degrees != 0) {
				matrix.postRotate(degrees);
			}
			Bitmap resizedBitmap = Bitmap.createBitmap(orignal, 0, 0, width,
					height, matrix, true);
			return resizedBitmap;
		}
		return orignal;
	}

	public static Bitmap resizeImageWithOrignal(Bitmap orignal, int maxDimension) {
		// load the origial BitMap
		int width = orignal.getWidth();
		int height = orignal.getHeight();

		if (width > maxDimension || height > maxDimension) {
			int new_width;
			int new_height;
			float ratio = (float) width / height;
			if (ratio > 1.0f) {
				new_width = maxDimension;
				new_height = (int) ((float) new_width / ratio);
			} else {
				new_height = maxDimension;
				new_width = (int) ((float) new_height * ratio);
			}
			float scaleWidth = ((float) new_width) / width;
			float scaleHeight = ((float) new_height) / height;
			Matrix matrix = new Matrix();
			matrix.postScale(scaleWidth, scaleHeight);
			Bitmap resizedBitmap = Bitmap.createBitmap(orignal, 0, 0, width,
					height, matrix, true);
			return resizedBitmap;
		}
		return orignal;
	}

	public static Bitmap getCornerBitmap(Bitmap bitmap) {

		if (bitmap != null) {
			Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
					bitmap.getHeight(), Config.ARGB_8888);
			Canvas canvas = new Canvas(output);

			final int color = 0xff424242;
			final Paint paint = new Paint();
			final Rect rect1 = new Rect(0, 0, bitmap.getWidth(),
					bitmap.getHeight());
			// final Rect rect1 = new Rect(2, 2, bitmap.getWidth() + 2, bitmap
			// .getHeight() + 2);
			final Rect rect = new Rect(0, 0, bitmap.getWidth(),
					bitmap.getHeight());
			// final Rect rect2 = new Rect(0, 0, bitmap.getWidth() + 4, bitmap
			// .getHeight() + 4);
			// final RectF rectF = new RectF(rect2);
			// final float roundPx = 0;

			paint.setAntiAlias(true);
			canvas.drawARGB(0, 0, 0, 0);
			paint.setColor(color);
			// paint.setStrokeWidth(1);
			canvas.drawColor(Color.WHITE);
			// paint.setStyle(Paint.Style.STROKE);
			// canvas.drawRect(rectF, paint);

			paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
			canvas.drawBitmap(bitmap, rect, rect1, paint);

			return output;
		} else {
			return bitmap;
		}
	}



	/**
	 * return array byte from a bitmap input
	 * 
	 * @author: BangHN
	 * @param imgPath
	 *            : duong dan anh -> get thuoc tinh anh
	 * @param bmInput
	 *            : anh bitmap truyen vao
	 * @param maxWidth
	 *            : chieu rong toi da anh mong muon
	 * @param maxHeight
	 *            : chieu cao anh toi da mong muon
	 * @return: byte array
	 */
	public static byte[] getByteArrayOfBitmap(Bitmap bmInput, int maxWidth,
			int maxHeight) throws Throwable {
		byte[] retBuffer = null;

		int bmW = bmInput.getWidth();
		int bmH = bmInput.getHeight();

		if (bmW <= 0 || bmH <= 0) {
			return null;
		}

		int width = bmW;
		int height = bmH;

		if (width < height) {// kiem tra anh duoc quay
			int tmp = width;
			width = height;
			height = tmp;
		}

		boolean withinBounds = (width <= maxWidth) && (height <= maxHeight);
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

		if (withinBounds) {
			try {
				bmInput.compress(Bitmap.CompressFormat.JPEG, 90,
						byteArrayOutputStream);
				// Gan ket qua tra ve
				retBuffer = byteArrayOutputStream.toByteArray();
			} catch (OutOfMemoryError e) {
				System.gc();
				throw e;
			} catch (Exception e) {
				throw e;
			} finally {
				bmInput = null;
			}
		} else {
			int newWidth = width;
			int newHeight = height;
			if (width > maxWidth || height > maxWidth) {
				float ratio = (float) width / height;
				if (ratio > 1.0f) {
					newWidth = maxWidth;
					newHeight = (int) ((float) newWidth / ratio);
				} else {
					newHeight = maxWidth;
					newWidth = (int) ((float) newHeight * ratio);
				}
			}

			Bitmap bitmap = Bitmap.createScaledBitmap(bmInput, newWidth,
					newHeight, false);
			bmInput.recycle();
			bmInput = null;

			if (bitmap != null) {
				bitmap.compress(Bitmap.CompressFormat.JPEG, 90,
						byteArrayOutputStream);
				bitmap.recycle();
				bitmap = null;
				retBuffer = byteArrayOutputStream.toByteArray();
				byteArrayOutputStream = null;
			}
		}
		System.gc();
		return retBuffer;
	}
	

	/**
	 * tinh sample size tu file
	 * 
	 * @author: PhucNT
	 * @return
	 * @return: int
	 * @throws:
	 */
	public static int computeSampleSizeFromFile(File file, int maxWidth, int maxHeight) {
		// TODO Auto-generated method stub
		if (maxWidth == 0 || maxHeight == 0)
			return 1;
		BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
		bmpFactoryOptions.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(file.getAbsolutePath(), bmpFactoryOptions);
		int heightRatio = (int) FloatMath.ceil(bmpFactoryOptions.outHeight
				/ (float) maxHeight);
		int widthRatio = (int) FloatMath.ceil(bmpFactoryOptions.outWidth
				/ (float) maxWidth);
		// If both of the ratios are greater than 1,
		// one of the sides of the image is greater than the screen
		bmpFactoryOptions.inSampleSize = 1;
		if (heightRatio > 1 && widthRatio > 1) {
			if (heightRatio > widthRatio) {
				// Height ratio is larger, scale according to it
				bmpFactoryOptions.inSampleSize = heightRatio;
			} else {
				// Width ratio is larger, scale according to it
				bmpFactoryOptions.inSampleSize = widthRatio;
			}
		}
		Log.e("BigPhotoCache", "bmpFactoryOptions.inSampleSize "
				+ bmpFactoryOptions.inSampleSize);

		return bmpFactoryOptions.inSampleSize;
	}
	public static Bitmap drawableToBitmap (Drawable drawable) 
	{
	    if (drawable instanceof BitmapDrawable) {
	        return ((BitmapDrawable)drawable).getBitmap();
	    }

	    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.RGB_565);
	    Canvas canvas = new Canvas(bitmap); 
	    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
	    drawable.draw(canvas);

	    return bitmap;
	    
	}
	/**
	*
	* 
	* @author: truong.le
	* @datetime: Nov 22, 2013 10:04:06 AM
	* @return: Bitmap
	* @param filePath
	* @returnTODO
	* 
	*/
	public static Bitmap decodeURI(String filePath)
    {
		Bitmap output = null;
		try
		{
	        Options options = new Options();
	        options.inJustDecodeBounds = true;
	        options.inPreferredConfig = Bitmap.Config.RGB_565;
	        options.inSampleSize = 2;
	        BitmapFactory.decodeFile(filePath, options);
	
	        // Only scale if we need to 
	        // (16384 buffer for img processing)
	        Boolean scaleByHeight = Math.abs(options.outHeight - 100) >= Math.abs(options.outWidth - 100);
	        if(options.outHeight * options.outWidth * 2 >= 16384){
	            // Load, scaling to smallest power of 2 that'll get it <= desired dimensions
	            double sampleSize = scaleByHeight
	                ? options.outHeight / 100
	                : options.outWidth / 100;
	            options.inSampleSize = 
	                (int)Math.pow(2d, Math.floor(
	                Math.log(sampleSize)/Math.log(2d)));
	        }
	
	        // Do the actual decoding
	        options.inJustDecodeBounds = false;
	        options.inTempStorage = new byte[512];  
	        output = BitmapFactory.decodeFile(filePath, options);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
        return output;
    }
	public static Bitmap getPath(Uri uri, Context context) {
		Bitmap bitmap = null;
		BitmapFactory.Options o = new BitmapFactory.Options();
		o.inJustDecodeBounds = true;
		o.inPreferredConfig = Bitmap.Config.RGB_565;
		/*BitmapFactory.decodeStream(context.getContentResolver()
				.openInputStream(uri), null, o);*/
		//BitmapFactory.decodeFile(uri.toString(), o);

		final int REQUIRED_SIZE = 100;

		int width_tmp = o.outWidth, height_tmp = o.outHeight;
		int scale = 1;
		while (true) {
			if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) {
				break;
			}
			width_tmp /= 2;
			height_tmp /= 2;
			scale *= 2;
		}

		BitmapFactory.Options o2 = new BitmapFactory.Options();
		o2.inSampleSize = scale;
		bitmap = BitmapFactory.decodeFile(uri.toString(), o2);
		/*bitmap = BitmapFactory.decodeStream(context.getContentResolver()
				.openInputStream(uri), null, o2);*/

		return bitmap;
	}
}
